#include "widget.h"
#include "ui_widget.h"
#include "config.h"
#include <QPainter>
#include <QMouseEvent>
#include <ctime>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    initScene();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::initScene()
{
    //设置场景尺寸
    setFixedSize(GAME_WIDTH, GAME_HEIGHT);

    //设置标题
    setWindowTitle(GAME_TITLE);

    //设置图标
    setWindowIcon(QIcon(GAME_TITLE_ICON));

    //设置定时器
    m_Timer.setInterval(GAME_RATE);

    //启动游戏
    playGame();

    //敌机出场间隔初始化
    m_recorder = 0;

    //随机数种子
    srand((unsigned int)time(NULL));
}

void Widget::playGame()
{
    //启动定时器
    m_Timer.start();

    //监视定时器发送的信号
    connect(&m_Timer, &QTimer::timeout, [=](){
        //敌机出场
        enemyToScene();


        //更新游戏中元素坐标
        updatePosition();

        //绘制到屏幕中
        update();

        //碰撞检测
        collisionDetection();
    });
}

void Widget::updatePosition()
{
    //更新地图坐标
    m_map.mapPosition();

    //发射子弹
    m_hero.shoot();

    //计算所有非空闲子弹坐标
    for(int i = 0; i < BULLET_NUM; i++){
        //如果非空闲，计算发射位置
        if(!m_hero.m_bullets[i].m_Free){
            m_hero.m_bullets[i].updatePosition();
        }
    }

    //敌机出场
    for(int i = 0; i < ENEMY_NUM; i++){
        //非空闲敌机
        if(!m_enemys[i].m_Free){
            m_enemys[i].updatePosition();
        }
    }

    //爆炸播放
    for(int i = 0; i< BOMB_NUM; i++){
        if(!m_bomns[i].m_Free){
            m_bomns[i].updateInfo();
        }
    }
}

void Widget::paintEvent(QPaintEvent *e)
{
    QPainter painter(this);

    //绘制地图
    painter.drawPixmap(0, m_map.m_map1_posY, m_map.m_map1);
    painter.drawPixmap(0, m_map.m_map2_posY, m_map.m_map2);

    //绘制飞机
    painter.drawPixmap(m_hero.m_X, m_hero.m_Y, m_hero.m_Plane);

    //绘制子弹
    for(int i = 0; i < BULLET_NUM; i++){
        //如果非空闲，绘制子弹
        if(!m_hero.m_bullets[i].m_Free){
            painter.drawPixmap(m_hero.m_bullets[i].m_X, m_hero.m_bullets[i].m_Y, m_hero.m_bullets[i].m_Bullet);
        }
    }

    //绘制敌机
    for(int i = 0; i < ENEMY_NUM; i++){
        //非空闲敌机
        if(!m_enemys[i].m_Free){
            painter.drawPixmap(m_enemys[i].m_X, m_enemys[i].m_Y, m_enemys[i].m_enemy);
        }
    }

    //绘制爆炸
    for(int i = 0; i< BOMB_NUM; i++){
        if(!m_bomns[i].m_Free){
            painter.drawPixmap(m_bomns[i].m_X, m_bomns[i].m_Y, m_bomns[i].m_pixArr[m_bomns[i].m_index]);
        }
    }
}

void Widget::mouseMoveEvent(QMouseEvent *e)
{
    int x = e->x() - (m_hero.m_Rect.width() * 0.5);
    int y = e->y() - (m_hero.m_Rect.height() * 0.5);

    //边界检测
    if(x <= 0){
        x = 0;
    }

    if(x >= GAME_WIDTH - m_hero.m_Rect.width()){
        x = GAME_WIDTH - m_hero.m_Rect.width();
    }

    if(y <= 0){
        y = 0;
    }

    if(y >= GAME_HEIGHT - m_hero.m_Rect.height()){
        y = GAME_HEIGHT - m_hero.m_Rect.height();
    }

    m_hero.setPosition(x, y);
}

void Widget::enemyToScene()
{
    m_recorder++;
    if(m_recorder < ENEMY_INTERVAL){
        return;
    }

    m_recorder = 0;

    for(int i = 0; i < ENEMY_NUM; i++){
        //如果是空闲飞机，出场
        if(m_enemys[i].m_Free){
            m_enemys[i].m_Free = false;

            //坐标
            m_enemys[i].m_X = rand() % (GAME_WIDTH - m_enemys[i].m_Rect.width());
            m_enemys[i].m_Y = -m_enemys[i].m_Rect.height();
            break;
        }
    }


}

void Widget::collisionDetection()
{
    //遍历所有非空闲敌机
    for(int i = 0; i < ENEMY_NUM; i++){
        //空闲飞机不处理
        if(m_enemys[i].m_Free){
            continue;
        }

        //遍历所有非空闲子弹
        for(int j = 0; j < BULLET_NUM; j++){
            //空闲子弹不处理
            if(m_hero.m_bullets[j].m_Free){
                continue;
            }

            //敌机与子弹相交,发生碰撞
            if(m_enemys[i].m_Rect.intersects(m_hero.m_bullets[j].m_Rect)){
                m_enemys[i].m_Free = true;
                m_hero.m_bullets[j].m_Free = true;

                //播放爆炸效果
                for(int k = 0; k < BOMB_NUM; k++){
                    if(m_bomns[k].m_Free){
                        //空闲爆炸，可以播放
                        m_bomns[k].m_Free = false;

                        //更新爆炸坐标
                        m_bomns[k].m_X = m_enemys[i].m_X;
                        m_bomns[k].m_Y = m_enemys[i].m_Y;
                        break;
                    }
                }
            }

        }
    }
}
